/** \file gu_uniform_map.cpp */

#include "gu_uniform_map.h"
#include "gu_shader.h"

#include"gr_algorithms.h"

#include<iterator>

#include <GL/glew.h>
#include<cstdint>
#include <cassert>


namespace gu {


class GLSL330UniformMap : public UniformMap
{
public:

    void uniformVec4(uint32_t key, float* data, int count)
    {
        glUniform4fv(key, count, data);
    }

    void uniformVec3(uint32_t key, float* data, int count)
    {
        glUniform3fv(key, count, data);
    }

    void uniformFloat(uint32_t key, float* data, int count)
    {
        glUniform1fv(key, count, data);
    }

    void uniformMat4(uint32_t key, float* data, int count)
    {
         glUniformMatrix4fv(key, count, GL_FALSE, data);
    }

    /* Implementing the public interface.*/

    void mapTo(ShaderLoc loc, float data) override
    {
        uniformFloat(loc, &data, 1);
    }

    void mapTo(ShaderLoc loc, gr::vec3& data) override
    {
        uniformVec3(loc, data.data(), 1);
    }

    void mapTo(ShaderLoc loc, gr::vec4& data) override
    {
        uniformVec4(loc, data.data(), 1);
    }

    void mapTo(ShaderLoc loc, gr::mat4& data) override
    {
        uniformMat4(loc, data.data(), 1);
    }

};


UniformMap* newUniformMap(ShaderDialect dialect)
{
    UniformMap* ptr = nullptr;
    switch(dialect)
    {
        case GLSL_330:  ptr = dynamic_cast<UniformMap*>(new GLSL330UniformMap()); break;
        default:assert(!"Unhandled enum value"); 
    }

    return ptr;
}


}
